<template>
  <div class="app-container">
    <!-- 统计卡片 -->
    <el-row :gutter="20" class="mb20">
      <el-col :span="6">
        <el-card class="card-panel">
          <div slot="header" class="clearfix card-header">
            <span>总设备数</span>
          </div>
          <div class="card-panel-icon-wrapper icon-total">
            <i class="el-icon-monitor icon-total" style="font-size: 36px;" />
          </div>
          <div class="card-panel-description">
            <div class="card-panel-text">{{ statistics.totalDevices }} <span class="card-panel-num">台</span></div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card class="card-panel">
          <div slot="header" class="clearfix card-header">
            <span>在线设备</span>
          </div>
          <div class="card-panel-icon-wrapper icon-online">
            <i class="el-icon-success icon-online" style="font-size: 36px;" />
          </div>
          <div class="card-panel-description">
            <div class="card-panel-text">{{ statistics.onlineDevices }} <span class="card-panel-num">台</span></div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card class="card-panel">
          <div slot="header" class="clearfix card-header">
            <span>离线设备</span>
          </div>
          <div class="card-panel-icon-wrapper icon-offline">
            <i class="el-icon-error icon-offline" style="font-size: 36px;" />
          </div>
          <div class="card-panel-description">
            <div class="card-panel-text">{{ statistics.offlineDevices }} <span class="card-panel-num">台</span></div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card class="card-panel">
          <div slot="header" class="clearfix card-header">
            <span>故障设备</span>
          </div>
          <div class="card-panel-icon-wrapper icon-error">
            <i class="el-icon-warning icon-error" style="font-size: 36px;" />
          </div>
          <div class="card-panel-description">
            <div class="card-panel-text">{{ statistics.faultDevices }} <span class="card-panel-num">台</span></div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 搜索表单 -->
    <el-form v-show="showSearch" ref="queryForm" :model="queryParams" size="small" :inline="true" label-width="68px">
      <el-form-item label="设备名称" prop="deviceName">
        <el-input
          v-model="queryParams.deviceName"
          placeholder="请输入设备名称"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="场所名称" prop="locationName">
        <el-input
          v-model="queryParams.locationName"
          placeholder="请输入场所名称"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="设备状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="请选择设备状态" clearable>
          <el-option
            v-for="dict in dict.type.device_status"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
        <el-button type="success" icon="el-icon-refresh" size="mini" @click="refreshData">刷新数据</el-button>
      </el-form-item>
    </el-form>

    <!-- 设备监控表格 -->
    <el-table v-loading="loading" :data="deviceList" style="width: 100%">
      <el-table-column label="设备ID" align="center" prop="deviceId" min-width="120" />
      <el-table-column label="设备名称" align="center" prop="deviceName" min-width="100" />
      <el-table-column label="场所名称" align="center" prop="locationName" min-width="120" />
      <el-table-column label="IP地址" align="center" prop="ipAddress" min-width="120" />
      <el-table-column label="设备状态" align="center" prop="status" min-width="100">
        <template slot-scope="scope">
          <el-tag
            :type="scope.row.status === 1 ? 'success' : scope.row.status === 0 ? 'danger' : 'warning'"
            effect="dark"
          >
            <i :class="scope.row.status === 1 ? 'el-icon-success' : scope.row.status === 0 ? 'el-icon-error' : 'el-icon-warning'" />
            {{ scope.row.status === 1 ? '在线' : scope.row.status === 0 ? '离线' : '故障' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="最后心跳时间" align="center" prop="lastHeartbeat" min-width="160">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.lastHeartbeat, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="心跳延迟" align="center" min-width="100">
        <template slot-scope="scope">
          <el-tag :type="getHeartbeatDelayType(scope.row.lastHeartbeat)">
            {{ getHeartbeatDelay(scope.row.lastHeartbeat) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="连接用户数" align="center" min-width="100">
        <template slot-scope="scope">
          <el-tag type="info">{{ scope.row.connectedUsers || 0 }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" min-width="200">
        <template slot-scope="scope">
          <el-button
            v-hasPermi="['device:monitor:query']"
            size="mini"
            type="text"
            icon="el-icon-view"
            @click="handleDetail(scope.row)"
          >详情</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-refresh"
            :disabled="scope.row.status === 0"
            @click="handleHeartbeat(scope.row)"
          >心跳测试</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-data-line"
            @click="handleHistory(scope.row)"
          >历史记录</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 设备详情对话框 -->
    <el-dialog title="设备监控详情" :visible.sync="detailOpen" width="800px" append-to-body>
      <el-descriptions v-if="deviceDetail" :column="2" border>
        <el-descriptions-item label="设备ID">{{ deviceDetail.deviceId }}</el-descriptions-item>
        <el-descriptions-item label="设备名称">{{ deviceDetail.deviceName }}</el-descriptions-item>
        <el-descriptions-item label="场所名称">{{ deviceDetail.locationName }}</el-descriptions-item>
        <el-descriptions-item label="场所地址">{{ deviceDetail.locationAddress }}</el-descriptions-item>
        <el-descriptions-item label="IP地址">{{ deviceDetail.ipAddress }}</el-descriptions-item>
        <el-descriptions-item label="MAC地址">{{ deviceDetail.macAddress }}</el-descriptions-item>
        <el-descriptions-item label="设备状态">
          <el-tag :type="deviceDetail.status === 1 ? 'success' : deviceDetail.status === 0 ? 'danger' : 'warning'">
            {{ deviceDetail.status === 1 ? '在线' : deviceDetail.status === 0 ? '离线' : '故障' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="最后心跳时间">{{ parseTime(deviceDetail.lastHeartbeat, '{y}-{m}-{d} {h}:{i}:{s}') }}</el-descriptions-item>
        <el-descriptions-item label="安装日期">{{ parseTime(deviceDetail.installDate, '{y}-{m}-{d}') }}</el-descriptions-item>
        <el-descriptions-item label="联系人">{{ deviceDetail.contactPerson }}</el-descriptions-item>
        <el-descriptions-item label="联系电话">{{ deviceDetail.contactPhone }}</el-descriptions-item>
        <el-descriptions-item label="设备型号">
          <dict-tag :options="dict.type.device_model" :value="deviceDetail.deviceModel" />
        </el-descriptions-item>
      </el-descriptions>

      <!-- 实时状态图表 -->
      <div style="margin-top: 20px;">
        <h4>设备状态趋势</h4>
        <div id="statusChart" style="height: 300px;" />
      </div>
    </el-dialog>

    <!-- 历史记录对话框 -->
    <el-dialog title="设备历史记录" :visible.sync="historyOpen" width="1000px" append-to-body>
      <el-table v-loading="historyLoading" :data="historyList">
        <el-table-column label="记录时间" align="center" prop="recordTime" min-width="160">
          <template slot-scope="scope">
            <span>{{ parseTime(scope.row.recordTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
          </template>
        </el-table-column>
        <el-table-column label="事件类型" align="center" prop="eventType" min-width="100">
          <template slot-scope="scope">
            <el-tag :type="scope.row.eventType === 'online' ? 'success' : scope.row.eventType === 'offline' ? 'danger' : 'warning'">
              {{ scope.row.eventType === 'online' ? '上线' : scope.row.eventType === 'offline' ? '下线' : '故障' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="状态描述" align="center" prop="description" min-width="200" />
        <el-table-column label="连接用户数" align="center" prop="connectedUsers" min-width="100" />
        <el-table-column label="响应时间(ms)" align="center" prop="responseTime" min-width="120" />
      </el-table>

      <pagination
        v-show="historyTotal>0"
        :total="historyTotal"
        :page.sync="historyParams.pageNum"
        :limit.sync="historyParams.pageSize"
        @pagination="getHistoryList"
      />
    </el-dialog>
  </div>
</template>

<script>
import { listDevice, getDeviceStatistics, updateHeartbeat } from '@/api/wifi/device'

export default {
  name: 'DeviceMonitor',
  dicts: ['device_status', 'device_model'],
  data() {
    return {
      // 遮罩层
      loading: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 设备信息表格数据
      deviceList: [],
      // 是否显示详情弹出层
      detailOpen: false,
      // 是否显示历史记录弹出层
      historyOpen: false,
      // 历史记录加载
      historyLoading: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        deviceName: null,
        locationName: null,
        status: null
      },
      // 设备详情
      deviceDetail: {},
      // 统计数据
      statistics: {
        totalDevices: 0,
        onlineDevices: 0,
        offlineDevices: 0,
        faultDevices: 0
      },
      // 历史记录数据
      historyList: [],
      historyTotal: 0,
      historyParams: {
        pageNum: 1,
        pageSize: 10,
        deviceId: null
      },
      // 自动刷新定时器
      refreshTimer: null
    }
  },
  created() {
    this.getList()
    this.getStatistics()
    this.startAutoRefresh()
  },
  beforeDestroy() {
    this.stopAutoRefresh()
  },
  methods: {
    /** 查询设备信息列表 */
    getList() {
      this.loading = true
      listDevice(this.queryParams).then(response => {
        this.deviceList = response.rows
        this.total = response.total
        this.loading = false
      })
    },
    /** 获取统计数据 */
    getStatistics() {
      getDeviceStatistics().then(response => {
        this.statistics = response.data
      })
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm('queryForm')
      this.handleQuery()
    },
    /** 刷新数据 */
    refreshData() {
      this.getList()
      this.getStatistics()
      this.$modal.msgSuccess('数据刷新成功')
    },
    /** 设备详情 */
    handleDetail(row) {
      this.deviceDetail = row
      this.detailOpen = true
      this.$nextTick(() => {
        this.initStatusChart()
      })
    },
    /** 心跳测试 */
    handleHeartbeat(row) {
      this.$modal.loading('正在测试设备心跳...')
      updateHeartbeat(row.deviceId).then(response => {
        this.$modal.closeLoading()
        this.$modal.msgSuccess('心跳测试成功')
        this.getList()
      }).catch(() => {
        this.$modal.closeLoading()
        this.$modal.msgError('心跳测试失败')
      })
    },
    /** 历史记录 */
    handleHistory(row) {
      this.historyParams.deviceId = row.deviceId
      this.historyOpen = true
      this.getHistoryList()
    },
    /** 获取历史记录 */
    getHistoryList() {
      this.historyLoading = true
      // 模拟历史记录数据
      setTimeout(() => {
        this.historyList = [
          {
            recordTime: new Date(Date.now() - 1000 * 60 * 30),
            eventType: 'online',
            description: '设备上线',
            connectedUsers: 15,
            responseTime: 25
          },
          {
            recordTime: new Date(Date.now() - 1000 * 60 * 60 * 2),
            eventType: 'offline',
            description: '设备离线',
            connectedUsers: 0,
            responseTime: 0
          },
          {
            recordTime: new Date(Date.now() - 1000 * 60 * 60 * 3),
            eventType: 'online',
            description: '设备重新上线',
            connectedUsers: 8,
            responseTime: 30
          }
        ]
        this.historyTotal = this.historyList.length
        this.historyLoading = false
      }, 500)
    },
    /** 计算心跳延迟 */
    getHeartbeatDelay(lastHeartbeat) {
      if (!lastHeartbeat) return '未知'
      const now = new Date()
      const last = new Date(lastHeartbeat)
      const diff = Math.floor((now - last) / 1000)

      if (diff < 60) return `${diff}秒前`
      if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`
      if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`
      return `${Math.floor(diff / 86400)}天前`
    },
    /** 获取心跳延迟类型 */
    getHeartbeatDelayType(lastHeartbeat) {
      if (!lastHeartbeat) return 'info'
      const now = new Date()
      const last = new Date(lastHeartbeat)
      const diff = Math.floor((now - last) / 1000)

      if (diff < 300) return 'success' // 5分钟内
      if (diff < 1800) return 'warning' // 30分钟内
      return 'danger' // 超过30分钟
    },
    /** 初始化状态图表 */
    initStatusChart() {
      // 确保引入了ECharts
      this.loadECharts(() => {
        const chartDom = document.getElementById('statusChart')
        if (chartDom && window.echarts) {
          const chart = window.echarts.init(chartDom)
          const option = {
            title: {
              text: '设备状态趋势',
              left: 'center'
            },
            tooltip: {
              trigger: 'axis'
            },
            legend: {
              data: ['在线', '离线', '故障'],
              top: 30
            },
            xAxis: {
              type: 'category',
              data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00']
            },
            yAxis: {
              type: 'value'
            },
            series: [
              {
                name: '在线',
                type: 'line',
                data: [1, 1, 1, 1, 1, 1, 1],
                smooth: true,
                itemStyle: { color: '#67C23A' }
              },
              {
                name: '离线',
                type: 'line',
                data: [0, 0, 0, 0, 0, 0, 0],
                smooth: true,
                itemStyle: { color: '#F56C6C' }
              },
              {
                name: '故障',
                type: 'line',
                data: [0, 0, 0, 0, 0, 0, 0],
                smooth: true,
                itemStyle: { color: '#E6A23C' }
              }
            ]
          }
          chart.setOption(option)
        } else {
          console.error('ECharts初始化失败，DOM元素或ECharts库不存在')
        }
      })
    },
    /** 加载ECharts库 */
    loadECharts(callback) {
      if (window.echarts) {
        callback()
        return
      }
      // 动态加载ECharts
      const script = document.createElement('script')
      script.src = 'https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js'
      script.onload = callback
      document.head.appendChild(script)
    },
    /** 开始自动刷新 */
    startAutoRefresh() {
      this.refreshTimer = setInterval(() => {
        this.getList()
        this.getStatistics()
      }, 30000) // 30秒刷新一次
    },
    /** 停止自动刷新 */
    stopAutoRefresh() {
      if (this.refreshTimer) {
        clearInterval(this.refreshTimer)
        this.refreshTimer = null
      }
    }
  }
}
</script>

<style scoped>
.mb20 {
  margin-bottom: 20px;
}

.card-header {
  font-size: 16px;
  font-weight: 600;
}

.card-panel {
  height: 140px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.card-panel-icon-wrapper {
  float: left;
  margin: 20px 0 0 20px;
  padding: 20px;
  transition: all 0.38s ease-out;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.card-panel-icon {
  float: left;
  font-size: 48px;
}

.card-panel-description {
  float: right;
  font-weight: bold;
  margin: 35px 30px;
  margin-left: 0px;
  text-align: center;
  width: 80px;
}

.card-panel-text {
  line-height: 30px;
  color: rgba(0, 0, 0, 0.45);
  font-size: 24px;
  margin-bottom: 5px;
  display: block;
}

.card-panel-num {
  font-size: 18px;
  display: inline;
  color: #606266;
  margin-left: 5px;
}

.icon-total {
  color: #40c9c6;
}

.icon-online {
  color: #36a3f7;
}

.icon-offline {
  color: #f4516c;
}

.icon-error {
  color: #f6ab40;
}

.icon-total,
.icon-online,
.icon-offline,
.icon-error {
  font-size: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
}
</style>
